use std::{collections::HashMap, vec};

use container_core::workflow::{SimpleWorkflowEngine, WorkflowDocumentJsonReader};
use model_graph_types::{
    container::workflow::{
        WorkflowDocumentReadeOptions, WorkflowDocumentReader, WorkflowEngine,
        WorkflowEngineCompileOptions, WorkflowEngineRunOptions, WorkflowGraphNode,
        WorkflowGraphNodeData, WorkflowGraphNodeHttpStatement, WorkflowGraphNodeStatement,
    },
    database::{ConnectorProtocol, DataSource as DatabaseDataSource, DatabaseType},
    datasource::{
        AttributeConditionBuilder, ClassRelationCondition, ClassRelationConditionBuilder,
        DataSourceConnector, MySQLStorageOption, QueryCondition, QueryConditionBuilder,
        QueryExtention, QueryExtentionBuilder, QueryOptions as DataSourceConnectorQueryOptions,
        RelationCondition, RelationConditionBuilder, SQLiteStorageOption, Storage,
    },
    modeling::{
        application::ApplicationConversation,
        assistant::{
            FormSchema, FormSchemaItem, Model, ModelProvider, ModelProviderSetting,
            ModelTypeSetting,
        },
        meta::SYSTEM_DOMAIN_IDENTIFIER,
        set_system_meta_database, system_meta_database, BitOperator, Class, ClassGetter,
        ClassRelation, ComparsionOperator, DataSourceEntity, Domain, LogicalOperator,
        MetaConnector, RelationDirection, Value,
    },
};

use datasource_connector::{
    connector::SimpleDataSourceConnector, modeling_connector::SimpleMetaConnector,
};
use serde_json::value;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    tracing_subscriber::fmt()
        .with_max_level(tracing::Level::DEBUG)
        .init();
    tracing::info!("RRAI 启动...");

    let op = LogicalOperator::BitOperator(BitOperator::And);

    tracing::debug!("{}", serde_json::to_string(&op)?);

    let op = LogicalOperator::And;

    tracing::debug!("{}", serde_json::to_string(&op)?);

    set_system_meta_database(DatabaseDataSource {
        id: 0,
        database_type: DatabaseType::SQLite,
        protocol: ConnectorProtocol::SQLite,
        url: String::from("sqlite:/Users/jinisu/rrg01/rrg01.sqlite"),
        ..Default::default()
    })?;

    // let datasource = DatabaseDataSource {
    //     id: 3,
    //     database_type: DatabaseType::MySQL,
    //     protocol: ConnectorProtocol::MySQL,
    //     url: String::from("mysql://root:6e4a1a8993be1628@39.106.1.82:8306/g01_meta"),
    //     username: None,
    //     password: None,
    //     options: None,
    // };
    let datasource2 = DatabaseDataSource {
        id: 1,
        database_type: DatabaseType::SQLite,
        protocol: ConnectorProtocol::SQLite,
        url: String::from("sqlite:/Users/jinisu/rrg01/rrg01.sqlite"),
        ..Default::default()
    };

    // let datasource2 = DatabaseDataSource {
    //     id: 1,
    //     database_type: DatabaseType::SQLite,
    //     protocol: ConnectorProtocol::SQLite,
    //     url: String::from("sqlite:c:/Users/jinisu/rrg01/app.sqlite"),
    //     ..Default::default()
    // };

    let mut ext2 = HashMap::new();
    ext2.insert(
        String::from("items"),
        (
            FormSchemaItem::get_identifier()?,
            QueryConditionBuilder::default()
                .relations(vec![ClassRelationConditionBuilder::default()
                    .conditions(
                        RelationConditionBuilder::default()
                            .related_at("schema_identifier")
                            .build()?,
                    )
                    .build()?])
                .build()?,
            None,
        ),
    );

    let mut ext = HashMap::new();
    ext.insert(
        String::from("provider_credential_schema"),
        (
            FormSchema::get_identifier()?,
            QueryConditionBuilder::default()
                .relations(vec![ClassRelationConditionBuilder::default()
                    .conditions(
                        RelationConditionBuilder::default()
                            .related_at("provider_form_schema")
                            .build()?,
                    )
                    .build()?])
                .build()?,
            Some(
                QueryExtentionBuilder::default()
                    .class_selector(ext2)
                    .build()?,
            ),
        ),
    );

    // __g01_domain 下所有的 class
    let mut conditions = QueryExtentionBuilder::default()
        .class_selector(ext)
        .build()?;

    let res = SimpleDataSourceConnector::default()
        .instance_query(
            &None,
            &datasource2,
            &ModelTypeSetting::get_identifier()?,
            QueryConditionBuilder::default()
                .attributes(vec![AttributeConditionBuilder::default()
                    .name("model_type")
                    .operator(ComparsionOperator::Equal)
                    .value("llm")
                    .build()?])
                .build()?,
            None,
            None,
        )
        .await?;
    // let mut res =
    //     SimpleMetaConnector::new_with_meta_datasource(&Some(system_meta_database()?))?
    //         .generate_sql(1, &String::from("_g01_desktop"), DatabaseType::SQLite)
    //         .await;
    tracing::debug!("{}", serde_json::to_string(&res).expect(""));
    // match res {
    //     Ok(response) => {
    //         tracing::debug!("{}", serde_json::to_string(&response).expect(""));
    //     }
    //     Err(err) => {
    //         tracing::error!("{:?}", err);
    //     }
    // }

    // let mut conditions = QueryCondition::with_relations(vec![
    //     ClassRelationCondition::with_class_codition(
    //         RelationCondition::with_class_identifier(
    //             RelationDirection::Reverse,
    //             String::from("rrg01_desktop_project"),
    //         )?,
    //         QueryCondition::with_attribute(
    //             String::from("project_identifier"),
    //             String::from("rrg01_proj_0001"),
    //         )?,
    //     )?,
    //     ClassRelationCondition::with_class_codition(
    //         RelationCondition::with_class_identifier(
    //             RelationDirection::Reverse,
    //             String::from("rrg01_project_application"),
    //         )?,
    //         QueryCondition::with_attribute(
    //             String::from("application_identifier"),
    //             String::from("test_app_002"),
    //         )?,
    //     )?,
    // ])?;

    // conditions.set_page(1, 10)?;

    // let mut res = SimpleDataSourceConnector::default()
    //     .instance_query(
    //         &None,
    //         &datasource2,
    //         &Domain::get_identifier()?,
    //         conditions,
    //         None,
    //         None,
    //     )
    //     .await;

    // match res {
    //     Ok(response) => {
    //         tracing::debug!("{:?}", response);
    //     }
    //     Err(err) => {
    //         tracing::error!("{:?}", err);
    //     }
    // }
    tokio::select! {
        _ = tokio::signal::ctrl_c() => {
            println!();
        }
    };
    tracing::info!("RRAI 结束...");
    Ok(())
}
